﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace GoodStuff.Web.Controls
{
    /// <summary>
    /// Generates a list of LinkButtons with minimum overhead on html and viewstate.
    /// All commands share a CommandArgument value, and will be rendered in a UL/LI list.
    /// </summary>
    [ParseChildrenAttribute (ChildrenAsProperties = true, DefaultProperty = "MenuItems")]
    public class CommandMenu : Control, IPostBackEventHandler
    {        
        private List<CommandMenuItem> _menuItems;

        /// <summary>
        /// A command event is fire whenever an enabled menuitem is clicked by the client.
        /// If this event is not handled, the command is bubbled.
        /// </summary>
        public event CommandEventHandler Command;

        /// <summary>
        /// The collection of menu items to show. You can also specify the commands
        /// in the .aspx file as children of the control, in the same way as ListBox works.
        /// </summary>
        public List<CommandMenuItem> MenuItems
        {
            get
            {
                if (_menuItems == null)
                {
                    _menuItems = new List<CommandMenuItem>();
                }
                return _menuItems;
            }           
        }

        public string CssClass { get; set; }

        protected override void Render(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
            writer.RenderBeginTag(HtmlTextWriterTag.Ul);

            foreach (CommandMenuItem item in this.MenuItems)
            {
                if (item.IsEnabled)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, "enabled");
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, "disabled");
                }

                writer.RenderBeginTag(HtmlTextWriterTag.Li);

                if (item.IsEnabled)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, this.Page.ClientScript.GetPostBackEventReference(new PostBackOptions(this, item.CommandName)));
                    writer.RenderBeginTag(HtmlTextWriterTag.A);
                }

                //writer.RenderBeginTag(HtmlTextWriterTag.Span);
                if (item.ImageUrl != null)
                {
                    writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, this.ResolveUrl(item.ImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, "glyph");
                    writer.RenderBeginTag(HtmlTextWriterTag.Span);
                    writer.RenderEndTag();  //Span
                    
                    //writer.AddAttribute(HtmlTextWriterAttribute.Src, this.ResolveUrl(item.ImageUrl));
                    //writer.AddAttribute(HtmlTextWriterAttribute.Valign, "absmiddle");
                    //writer.RenderBeginTag(HtmlTextWriterTag.Img);
                    //writer.RenderEndTag();  //Img
                    writer.Write("&nbsp;");
                }

                writer.Write(item.Name);
                //writer.RenderEndTag(); //Span

                if (item.IsEnabled)
                {
                    writer.RenderEndTag(); // A
                }

                writer.RenderEndTag();  //LI
            }

            writer.RenderEndTag();  //UL
        }

        /// <summary>
        /// For every menuitem the commandargument is the same. This is great for providing different
        /// command for the same item.
        /// </summary>
        public string CommandArgument
        {
            get
            {
                return ViewState["CommandArgument"] as string;
            }
            set
            {
                ViewState["CommandArgument"] = value;
            }
        }

        /// <summary>
        /// The CssClass that is being rendered. 
        /// </summary>
        //public string CssClass
        //{
        //    get
        //    {
        //        return ViewState["CssClass"] as string;
        //    }
        //    set
        //    {
        //        ViewState["CssClass"] = value;
        //    }
        //}

        void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
        {
            if (Command != null)
            {
                Command(this, new CommandEventArgs(eventArgument, this.CommandArgument));
            }
            else
            {
                RaiseBubbleEvent(this, new CommandEventArgs(eventArgument, this.CommandArgument));
            }
        }
    }
}
